<?php
/**
 * Geneone: Content Management Framework
 * Generic File
 *
 * http://geneone.neondragon.net/
 *
 * @package Geneone
 * @author Khlo
 * @version 1.0
 * @copyright 2004-2006 Geneone Development Team
 */
 
class Gene_File_Common {
	/**
	 * @var integer File ID
	 */
	var $fileId;
	
	/**
	 * @var array File Info
	 */
	var $fileInfo;
	
	/**
	 * @var string File Content
	 */
	var $fileContent = null;
	
	/**
	 * Returns a Gene file object.
	 *
	 * $file =& Gene_File_Common::get($fileId);
	 *
	 * @static
	 *
	 * @var integer $fileId File ID
	 */
	function &get($fileId) {
		$db =& Gene::getDatabase();
		
		$q = $db->prepare ("SELECT * FROM ".Gene::tableName("files")." WHERE file_id=?");
		$res = $q->execute(array((int)$fileId));
		$file = $res->fetchRow();
		$res->free();

		if ($file) {
			// Extra Functions are not applicable to all images e.g. SVG has image/svg+xml so
			// we can't just check for image/* 
			if (in_array($file['mime_type'], array("image/gif", "image/jpeg", "image/png"))) {
				require_once ("Gene/File/Image.php");
				$f =& new Gene_File_Image;
			} else {
				$f =& new Gene_File_Common;
			}
			$f->fileId = $file['file_id'];
			$f->fileInfo = $file;
		} else {
			$f = false;
		}
		
		return $f;
	}
	
	/**
	 * Returns a new Gene file object.
	 *
	 * Remember to call save() to get a file ID and to save file.
	 *
	 * @static
	 *
	 * @var string $mimeType File MIME Type
	 */
	function &create($mimeType) {
		if (in_array($mimeType, array("image/gif", "image/jpeg", "image/png"))) {
			require_once ("Gene/File/Image.php");
			$f =& new Gene_File_Image;
		} else {
			$f =& new Gene_File_Common;
		}
		
		$user =& Gene::getUser();
		
		$f->fileInfo = array(
			"mime_type" => $mimeType,
			"size" => 0,
			"owner_id" => $user->getUserId(),
			"t_create" => 0,
			"t_modify" => 0,
			"p_view" => "*",
			"p_edit" => "o",
			"system" => false,
		);
		
		return $f;
	}
	
	/**
	 * Returns the ID of the current file. Objects which
	 * have been created but not saved *will not* have an ID.
	 *
	 * @return integer File ID
	 */
	function getId() {
		return $this->fileId;
	}
	
	/**
	 * Returns the content of the file.
	 *
	 * @return string File Content
	 */
	function getContent() {
		if ($this->fileContent === null) {
			if (Gene::getSetting("file_storage") == "database") {
				$db =& Gene::getDatabase();
				
				$q = $db->prepare("SELECT file FROM ".Gene::tableName("file_storage")." WHERE file_id=?");
				$res = $q->execute(array($this->fileId));
				$this->fileContent = $res->fetchOne();
				$res->free();
			} else {
			}
		}
				
		return $this->fileContent;
	}
	
	/**
	 * Sets the content of the file.
	 *
	 * @var string $content File Content
	 */
	function setContent($content) {
		$this->fileInfo['size'] = strlen($content);
		$this->fileContent = $content;
	}
	
	/**
	 * Sets whether the file is a system file. A system file is a file used by
	 * the software (e.g. avatars, forum icons) rather than normal random
	 * attachments.
	 *
	 * @var boolean $system Whether the file is a system file
	 */
	function setSystem($system) {
		$this->fileInfo['system'] = (bool)$system;
	}

	/**
	 * Saves the current state of the file.
	 */
	function save() {
		$db =& Gene::getDatabase();
		
		if (isset($this->fileInfo['file_id'])) {
		} else {
			// Create a new file
			$fileId = $db->nextId(Gene::tableName("files"));
			
			$this->fileInfo['file_id'] = $fileId;
			$this->fileInfo['t_create'] = time();
			
			$db->extended->autoExecute(
				Gene::tableName("files"),
				$this->fileInfo,
				MDB2_AUTOQUERY_INSERT
			);
			
			if (Gene::getSetting("file_storage") == "database") {
				$db->extended->autoExecute(
					Gene::tableName("file_storage"),
					array(
						"file_id" => $fileId,
						"file" => $this->fileContent
					),
					MDB2_AUTOQUERY_INSERT
				); 
			} else {
			}
			
			$this->fileId = $fileId;
		}
	}
	
	/**
	 * Creates a new Gene_File object with the same content.
	 *
	 * @return object Gene_File_Image
	 */
	function &cloneFile() {
		$f =& Gene_File_Common::create($this->fileInfo['mime_type']);
		$f->setContent($this->getContent());
		return $f;
	}
	
	/**
	 * Checks whether the user can perform a certain action.
	 * Don't use this; use canView(), canEdit(), etc.
	 *
	 * @access private
	 *
	 * @var string $permission Name of the permission. view or edit.
	 *
	 * @return boolean
	 */
	function checkPermission($type) {
		$user =& Gene::getUser();
		
		if ($type != 'view' AND $type != 'edit') {
			return false;
		}
		
		$usermasks = $user->getPermissionMasks();
		$objectmasks = explode(",", $this->fileInfo['p_'.$type]);
		
		$c = false;

		foreach ($objectmasks as $i) {
			if ($i == "o") {
				if ($file['owner_id'] == $user->getUserId()) {
					$c = true;
				}
			} else if (in_array($i, $usermasks)) {
				$c = true;
			}
		}
		
		return $c;
	}
	
	/**
	 * Returns whether the user can view this file.
	 *
	 * @return boolean
	 */
	function canView() {
		return $this->checkPermission('view');
	}
	
	/**
	 * Returns whether the user can edit this file.
	 *
	 * @return boolean
	 */
	function canEdit() {
		return $this->checkPermission('edit');
	}
}
 
?>